package org.dllwh.utils.google;

import cn.hutool.core.collection.CollectionUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.dllwh.utils.google.config.OkHttpConfig;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import redis.clients.jedis.params.Params;

import java.io.IOException;
import java.net.SocketTimeoutException;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 把今天最好的表现当作明天最新的起点．．～
 * <p>
 * Today the best performance as tomorrow the newest starter!
 *
 * @ClassName OkHttpHelper
 * @Description OkHttpClient常用工具类
 * @Date 2025-05-30 9:28
 * @版本 V 1.0.1
 * @since JDK 17
 */
@Slf4j
public class OkHttpHelper {
    private static volatile OkHttpClient okHttpClient = null;

    /**
     * 创建OkHttpClient对象
     */
    private static OkHttpClient buildOKHttpClient() {
        if (okHttpClient == null) {
            synchronized (OkHttpHelper.class) {
                if (okHttpClient == null) {
                    okHttpClient = new OkHttpClient.Builder()
                            .callTimeout(OkHttpConfig.callTimeout, TimeUnit.SECONDS)
                            .connectTimeout(OkHttpConfig.connectTimeout, TimeUnit.SECONDS)
                            .readTimeout(OkHttpConfig.readTimeout, TimeUnit.SECONDS)
                            .writeTimeout(OkHttpConfig.writeTimeout, TimeUnit.SECONDS)
                            .retryOnConnectionFailure(OkHttpConfig.retryOnConnectionFailure)
                            .build();
                }
            }
        }
        return okHttpClient;
    }

    /**
     * 同步GET请求
     *
     * @param url          请求的url
     * @param headerParams 请求头信息
     * @param queryParams  请求的参数，在请求的url？后面的数据，没有可以传null
     */
    public static String getSyncRequest(String url, @Nullable Map<String, String> headerParams, @Nullable Map<String, String> queryParams) throws IOException {
        OkHttpClient okHttpClient = buildOKHttpClient();
        url = buildQuery(url, queryParams);
        Request request = new Request.Builder().get().url(url).build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful()) {
                return response.body() != null ? response.body().string() : null;
            } else {
                throw new RuntimeException("同步GET请求异常,错误码为: " + response.code());
            }
        }
    }


    /**
     * 异步Get请求
     *
     * @param url          请求地址
     * @param headerParams 请求头信息
     * @param queryParams  请求的参数，在请求的url？后面的数据，没有可以传null
     */
    public static String getAsyncRequest(String url, @Nullable Map<String, String> headerParams, @Nullable Map<String, String> queryParams) {
        OkHttpClient okHttpClient = buildOKHttpClient();
        Request.Builder request = new Request.Builder();
        buildHeader(request, headerParams);
        url = buildQuery(url, queryParams);
        request.get().url(url);

        Call call = okHttpClient.newCall(request.build());
        final int[] serversLoadTimes = {0};
        // 通过调用Call对象的enqueue方法就会执行异步请求，并且会根据请求成功与否执行相应的回调
        call.enqueue(new Callback() {
            // 请求失败后的处理
            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException exception) {
                // 如果超时并未超过指定次数，则重新连接
                if (exception.getCause().equals(SocketTimeoutException.class) && serversLoadTimes[0] < OkHttpConfig.maxLoadTimes) {
                    serversLoadTimes[0]++;
                    okHttpClient.newCall(request.build()).enqueue(this);
                }
                throw new RuntimeException("异步GET请求异常: ", exception);
            }

            // 请求成功后的处理
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) {
                try (ResponseBody responseBody = response.body()) {
                    if (response.isSuccessful()) {
                        log.info("异步GET请求成功调用");
                    } else {
                        throw new RuntimeException("异步GET请求异常,错误码为: " + response.code());
                    }
                }
            }
        });
        return url;
    }

    /**
     * 同步POST请求
     *
     * @param url         请求地址
     * @param queryParams form 提交的参数，在请求的url？后面的数据，没有可以传null
     */
    public static String postSyncRequest(String url, @Nullable Map<String, String> queryParams) throws IOException {
        OkHttpClient okHttpClient = buildOKHttpClient();
        FormBody.Builder formBody = new FormBody.Builder();
        if (CollectionUtil.isNotEmpty(queryParams)) {// 添加参数
            queryParams.forEach(formBody::add);
        }
        Request request = new Request.Builder().post(formBody.build()).url(url).build();
        Call call = okHttpClient.newCall(request);
        try (Response response = call.execute()) {
            // 根据响应结果判断
            if (response.isSuccessful()) {
                return response.body() != null ? response.body().string() : null;
            } else {
                throw new RuntimeException("同步POST请求异常,错误码为: " + response.code());
            }
        }
    }

    /**
     * 同步POST请求
     *
     * @param url 请求地址
     */
    public static String postSyncRequest(String url, String jsonParams) throws IOException {
        RequestBody requestBody = RequestBody.create(jsonParams, MediaType.parse("application/json; charset=utf-8"));
        Request request = new Request.Builder()
                .url(url)
                .post(requestBody)
                .build();
        try (Response response = okHttpClient.newCall(request).execute()) {
            if (response.isSuccessful()) {
                return response.body() != null ? response.body().string() : null;
            } else {
                throw new RuntimeException("同步POST请求异常,错误码为: " + response.code());
            }
        }
    }

    /**
     * 异步的post请求
     *
     * @param url         请求地址
     * @param queryParams 请求的参数，在请求的url？后面的数据，没有可以传null
     */
    public static String postAsyncRequest(String url, @Nullable Map<String, String> queryParams) {
        return null;
    }

    /**
     * 添加请求头
     *
     * @param requestBuilder 请求
     * @param headerParams   请求的头参数
     */
    private static Request.Builder buildHeader(Request.Builder requestBuilder, @Nullable Map<String, String> headerParams) {
        if (CollectionUtil.isNotEmpty(headerParams)) {
            headerParams.forEach(requestBuilder::header);
        }
        return requestBuilder;
    }

    /**
     * 添加请求数
     *
     * @param url         请求
     * @param queryParams 请求的参数
     */
    public static String buildQuery(String url, @Nullable Map<String, String> queryParams) {
        if (CollectionUtil.isNotEmpty(queryParams)) {
            String queryString = queryParams.entrySet().stream()
                    .map(entry -> entry.getKey() + "=" + entry.getValue())
                    .collect(Collectors.joining("&"));
            url = url + (url.contains("?") ? "&" : "?") + queryString;
        }
        return url;
    }

    /**
     * 添加请求参数
     *
     * @param requestBuilder 请求
     * @param bodyParams     请求的body数
     */
    private static void buildBody(Request.Builder requestBuilder, @Nullable Map<String, String> bodyParams) {

    }

    /**
     * 构建  POST 请求
     *
     * @param url    请求地址
     * @param params 请求的参数
     */
    private Request buildPostRequest(String url, Params... params) {
        return null;
    }

    /**
     * 同步请求
     */
    private Response sync() {
        return null;
    }

    /**
     * 异步请求，有返回值
     */
    private String async() {
        return null;
    }

    private void sendFailedStringCallback(Request request, Exception e) {

    }

    private void sendSuccessResultCallback(Object object) {

    }
}

